package com.rank.list.controller;

import cn.hutool.json.JSONUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.DefaultTypedTuple;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.data.redis.core.ZSetOperations.TypedTuple;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashSet;
import java.util.Set;

/**
 * @author John Doe Tang
 * @date 2021年06月26日 20:06
 */
@RestController
public class RankListController {

  @Autowired private StringRedisTemplate redisTemplate;

  public static final String SCORE_RANK = "score_rank";

  @GetMapping("/batchAdd")
  public void batchAdd() {
    Set<TypedTuple<String>> tuples = new HashSet<>();
    long start = System.currentTimeMillis();
    for (int i = 0; i < 100000; i++) {
      DefaultTypedTuple<String> tuple = new DefaultTypedTuple<>("张三" + i, 1D + i);
      tuples.add(tuple);
    }
    System.out.println("循环时间:" + (System.currentTimeMillis() - start) / 100 + "s");
    Long num = redisTemplate.opsForZSet().add(SCORE_RANK, tuples);
    System.out.println("批量新增时间:" + (System.currentTimeMillis() - start) / 100 + "s");
    System.out.println("受影响行数：" + num);
  }

  @GetMapping("/list")
  public void list() {
    Set<String> range = redisTemplate.opsForZSet().reverseRange(SCORE_RANK, 0, 10);
    System.out.println("获取到的排行列表:" + JSONUtil.toJsonStr(range));
    Set<ZSetOperations.TypedTuple<String>> rangeWithScores =
        redisTemplate.opsForZSet().reverseRangeWithScores(SCORE_RANK, 0, 10);
    System.out.println("获取到的排行和分数列表:" + JSONUtil.toJsonStr(rangeWithScores));
  }

  /**
   * 单个新增
   *
   * @author John Doe Tang
   * @date 2021/6/26 0026 20:24
   */
  @GetMapping("/add")
  public void add() {
    redisTemplate.opsForZSet().add(SCORE_RANK, "李四", 8899);
  }

  /**
   * 获取单个的排行
   *
   * @author John Doe Tang
   * @date 2021/6/26 0026 20:25
   */
  @GetMapping("/find")
  public void find() {
    Long rankNum = redisTemplate.opsForZSet().reverseRank(SCORE_RANK, "张三99999");
    System.out.println("李四的个人排名：" + rankNum);

    Double score = redisTemplate.opsForZSet().score(SCORE_RANK, "张三99999");
    System.out.println("李四的分数:" + score);
  }

  /**
   * 统计两个分数之间的人数
   *
   * @author John Doe Tang
   * @date 2021/6/26 0026 20:25
   */
  @GetMapping("/count")
  public void count() {
    Long count = redisTemplate.opsForZSet().count(SCORE_RANK, 8001, 9000);
    System.out.println("统计8001-9000之间的人数:" + count);
  }

  /**
   * 获取整个集合的基数(数量大小)
   *
   * @author John Doe Tang
   * @date 2021/6/26 0026 20:25
   */
  @GetMapping("/zCard")
  public void zCard() {
    Long aLong = redisTemplate.opsForZSet().zCard(SCORE_RANK);
    System.out.println("集合的基数为：" + aLong);
  }

  /**
   * 使用加法操作分数
   *
   * @author John Doe Tang
   * @date 2021/6/26 0026 20:26
   */
  @GetMapping("/incrementScore")
  public void incrementScore() {
    Double score = redisTemplate.opsForZSet().incrementScore(SCORE_RANK, "李四", 1000);
    System.out.println("李四分数+1000后：" + score);
  }
}
